package com.zdw.zfw.admin.modular.system.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zdw.zfw.admin.config.properties.ZfwProperties;
import com.zdw.zfw.admin.core.constants.SysConstants;
import com.zdw.zfw.admin.core.util.PasswordUtils;
import com.zdw.zfw.admin.core.util.ShiroUtils;
import com.zdw.zfw.admin.modular.system.model.entity.LoginUser;
import com.zdw.zfw.admin.modular.system.model.entity.SysUser;
import com.zdw.zfw.admin.modular.system.model.vo.LoginUserVO;
import com.zdw.zfw.admin.modular.system.service.ISysUserService;
import com.zdw.zfw.core.enums.ZfwExceptionInfoEnum;
import com.zdw.zfw.core.http.HttpResult;
import com.zdw.zfw.core.page.PageRequest;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;

/**
 * 用户控制器
 *
 * @author zdw
 * @date Oct 29, 2018
 */
@RestController
@RequestMapping("user")
@RequiresAuthentication
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysUserController {

	/**
	 * 用户 service
	 */
	private final ISysUserService sysUserService;

	/**
	 * 框架配置项
	 */
	private final ZfwProperties zfwProperties;

	private static final String SUFFIX = "_avatar.png";

	/**
	 * 新增/修改 用户
	 *
	 * @param record 用户
	 * @return HttpResult
	 */
	@RequiresPermissions({"sys:user:add", "sys:user:edit"})
	@PostMapping(value="/save")
	public HttpResult save(@RequestBody SysUser record) {
		SysUser user = sysUserService.findById(record.getId());
		if(user != null) {
			if(SysConstants.ADMIN.equalsIgnoreCase(user.getName())) {
				return HttpResult.error("超级管理员不允许修改!");
			}
		}
		if(record.getPassword() != null) {
			String salt = PasswordUtils.getSalt();
			if(user == null) {
				// 新增用户
				if(sysUserService.findByName(record.getName()) != null) {
					return HttpResult.error("用户名已存在!");
				}
				String password = PasswordUtils.encrypte(record.getPassword(), salt);
				record.setSalt(salt);
				record.setPassword(password);
			} else {
				// 修改用户, 且修改了密码
				if(!record.getPassword().equals(user.getPassword())) {
					String password = PasswordUtils.encrypte(record.getPassword(), salt);
					record.setSalt(salt);
					record.setPassword(password);
				}
			}
		}
		return HttpResult.success(sysUserService.saveRecord(record));
	}


	/**
	 * 删除 用户
	 *
	 * @param records 用户
	 * @return HttpResult
	 */
	@RequiresPermissions("sys:user:delete")
	@PostMapping(value="/delete")
	public HttpResult delete(@RequestBody List<SysUser> records) {
		for(SysUser record:records) {
			SysUser sysUser = sysUserService.findById(record.getId());
			if(sysUser != null && SysConstants.ADMIN.equalsIgnoreCase(sysUser.getName())) {
				return HttpResult.error("超级管理员不允许删除!");
			}
		}
		return HttpResult.success(sysUserService.delete(records));
	}
	
	@GetMapping(value="/findByName")
	public HttpResult findByUserName(@RequestParam String name) {
		return HttpResult.success(sysUserService.findByName(name));
	}
	
	@GetMapping(value="/findPermissions")
	public HttpResult findPermissions(@RequestParam String name) {
		return HttpResult.success(sysUserService.findPermissions(name));
	}
	
	@GetMapping(value="/findUserRoles")
	public HttpResult findUserRoles(@RequestParam Long userId) {
		return HttpResult.success(sysUserService.findUserRoles(userId));
	}

	@PostMapping(value="/findPage")
	public HttpResult findPage(@RequestBody PageRequest pageRequest) {
		return HttpResult.success(sysUserService.findPage(pageRequest));
	}

	/**
	 * 修改登录用户密码
	 */
	@GetMapping("/updatePassword")
	public HttpResult updatePassword(@RequestParam String password, @RequestParam String newPassword) {
		// 获取当前用户
		LoginUser user = ShiroUtils.getUser();
		assert user != null;

		// 根据用户名查询用户密码、盐
		SysUser sysUser = sysUserService.getOne(
				new QueryWrapper<SysUser>().select("salt, password, id").eq("name", user.getName()));

		if(password != null && newPassword != null) {
			String oldPassword = PasswordUtils.encrypte(password, sysUser.getSalt());
			if(!oldPassword.equals(sysUser.getPassword())) {
				return HttpResult.error(ZfwExceptionInfoEnum.OLD_PWD_NOT_RIGHT);
			}
				sysUser.setPassword(PasswordUtils.encrypte(newPassword, sysUser.getSalt()));
				return HttpResult.success(sysUserService.saveRecord(sysUser));
		}
		return HttpResult.error();
	}

	/**
	 * 上传头像
	 *
	 * @param picture 头像图片
	 */
	@PostMapping("/uploadAvatar")
	public HttpResult uploadAvatar(@RequestPart("file") MultipartFile picture) throws IOException {
		File desFile = new File(String.format("%s%d%s", zfwProperties.getAvatarAddress(), ShiroUtils.getUser().getId(), SUFFIX));
        picture.transferTo(desFile);
        return HttpResult.success();
	}

	/**
	 * 获取当前用户头像
	 *
	 * @throws IOException IO异常
	 */
	@GetMapping("/Avatar.png")
	public HttpResult getAvatar() throws IOException {
		File avatar = new File(String.format("%s%d%s", zfwProperties.getAvatarAddress(), Objects.requireNonNull(ShiroUtils.getUser()).getId(), SUFFIX));
		if (!avatar.exists()) {
			avatar= ResourceUtils.getFile("classpath:default_avatar.png");
		}
		InputStream in = new FileInputStream(avatar);
		byte[] bytes=new byte[(int)avatar.length()];
		in.read(bytes);
		Object base64EncoderImg = new BASE64Encoder().encode(bytes);
		return HttpResult.success(base64EncoderImg);
	}

	/**
	 * 获取登录用户非敏感信息
	 *
	 * @return 登录用户
	 */
	@GetMapping("/loginUser")
	public HttpResult getLoginUser(){
		LoginUserVO loginUserVO = new LoginUserVO();
		BeanUtil.copyProperties(ShiroUtils.getUser(), loginUserVO);
		return HttpResult.success(loginUserVO);
	}

	/**
	 * 更新当前登录用户的信息
	 *
	 * @param loginUserVO 登录用户
	 * @return 结果
	 */
	@PutMapping("/loginUser")
	public HttpResult updateLoginUser(@RequestBody LoginUserVO loginUserVO){
		if(SysConstants.ADMIN.equalsIgnoreCase(loginUserVO.getName())) {
			return HttpResult.error("超级管理员不允许修改!");
		}
		if (!Objects.requireNonNull(ShiroUtils.getUser()).getId().equals(loginUserVO.getId())) {
			return HttpResult.error("只允许修改当前登录用户!");
		}
		SysUser sysUser = new SysUser();
		BeanUtil.copyProperties(loginUserVO, sysUser);
		sysUserService.saveRecord(sysUser);
		return HttpResult.success(loginUserVO);
	}
}
